﻿using System;
using System.Threading;
using System.Threading.Tasks;

namespace 内核模式之ReaderWriteLock读写锁
{
    class Program
    {

        /****
         * 如果写入的时间太久，这个时候的读线程会被卡住
         * 同样读取时间太长，也会导致写线程进不来  DB同样也是
         * 
         * 
         * ******/

        static ReaderWriterLock rwLock = new ReaderWriterLock();

        /***
         * 限制线程数的一个机制
         * 初始设置线程上限，当使用一个就会 -- 直到为0，相当于执行结束，
         * 
         * Reset： 重置当前的threadcount上线
         * Signal：将当前的threadcount--操作
         * Wait： 相当于我们的Task.WaitAll
         * 
         * ***/
        static CountdownEvent  countdown=new CountdownEvent(10);

        static void Main(string[] args)
        {
            //TestReadWrite();
            TestCountDown();
            Console.Read();

        }


        public static void TestCountDown()
        { 
            //重置上限
            countdown.Reset(10);
            for (int i = 0; i < 10; i++)
            {
                Task.Factory.StartNew(() =>
                {
                    LoadOrders();
                });
            }
            countdown.Wait();
            Console.WriteLine("所有orders加载完毕。。。。。。。。。。");

            countdown.Reset(5);
            for (int i = 0; i < 5; i++)
            {
                Task.Factory.StartNew(() =>
                {
                    LoadProducts();
                });
            }
            countdown.Wait();
            Console.WriteLine("所有Products加载完毕。。。。。。。。。。");

            countdown.Reset(2);
            for (int i = 0; i < 2; i++)
            {
                Task.Factory.StartNew(() =>
                {
                    LoadUsers();
                });
            }
            countdown.Wait();
            Console.WriteLine("所有Users加载完毕。。。。。。。。。。");

            Console.WriteLine("所有数据加载完毕。。");

        }



        static void TestReadWrite()
        {
            for (int i = 0; i < 5; i++)
            {
                Task.Factory.StartNew(() =>
                {
                    Read();
                });
            }
            Task.Factory.StartNew(() => {
                Write();
            });
        }
        public static void Read()
        {
            while (true)
            {
                Thread.Sleep(10);
                rwLock.AcquireReaderLock(int.MaxValue);
                Thread.Sleep(10);
                Console.WriteLine($"当前读取操作,tid={Thread.CurrentThread.ManagedThreadId},date={DateTime.Now}");
                rwLock.ReleaseReaderLock();
            }
        
        }
        public static void Write()
        {
            while (true)
            {
                //3s写一次
                Thread.Sleep(3000);
                rwLock.AcquireWriterLock(int.MaxValue);
                Thread.Sleep(3000);
                Console.WriteLine($"==========================当前写入操作,tid={Thread.CurrentThread.ManagedThreadId},==============date={DateTime.Now}");
                rwLock.ReleaseWriterLock();
            }

        }


        public static void LoadOrders()
        {
            Console.WriteLine( $"Orders数据加载！！！---{Thread.CurrentThread.ManagedThreadId}");
            countdown.Signal(); //-- 操作
        }

        public static void LoadProducts()
        {
            Console.WriteLine($"Products数据加载！！！---{Thread.CurrentThread.ManagedThreadId}");
            countdown.Signal();
        }
        public static void LoadUsers()
        {
            Console.WriteLine($"Users数据加载！！！---{Thread.CurrentThread.ManagedThreadId}");
            countdown.Signal();
        }

    }
}
